package com.imis.base.util.table.service.impl;

import com.imis.base.constant.CommonConstant;
import com.imis.base.constant.ConverterIgnoreConstant;
import com.imis.base.constant.DataBaseConstant;
import com.imis.base.util.ConvertUtils;
import com.imis.base.util.table.model.ColumnMeta;
import com.imis.base.util.table.service.IDataBaseTableHandleService;
import com.imis.module.online.table.model.po.TableIndex;

/**
 * <p>
 * DataBaseTableMySqlHandleServiceImpl<br>
 * MySql 数据库表处理服务 实现
 * </p>
 *
 * @author XinLau
 * @version 1.0
 * @since 2020年09月28日 17:36
 */
public class DataBaseTableMySqlHandleServiceImpl implements IDataBaseTableHandleService {

    /**
     * 将get...FieldDesc这些方法中共同的内容抽出来
     *
     * @param formColumnMeta - 前端表单
     * @param dataColumnMeta - 数据库表
     * @return String - SQL语句
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/10 14:17
     */
    private String getFieldDesc(final ColumnMeta formColumnMeta, final ColumnMeta dataColumnMeta) {
        StringBuilder sql = new StringBuilder();
        if (formColumnMeta.getColumnType().equalsIgnoreCase(DataBaseConstant.STRING)) {
            sql.append(formColumnMeta.getColumnName()).append(DataBaseConstant.SPACE).append(DataBaseConstant.VARCHAR).append(DataBaseConstant.LEFT_BRACKET)
                    .append(formColumnMeta.getColumnSize()).append(DataBaseConstant.RIGHT_BRACKET).append(DataBaseConstant.SPACE)
                    .append((CommonConstant.TO_UPPER_CASE_Y.equals(formColumnMeta.getIsNullable()) ? DataBaseConstant.SQL_NULL : DataBaseConstant.SQL_NOT_NULL));
        } else if (DataBaseConstant.DATE_.equalsIgnoreCase(formColumnMeta.getColumnType())) {
            sql.append(formColumnMeta.getColumnName()).append(DataBaseConstant.SPACE).append(DataBaseConstant.DATE_TIME_).append(DataBaseConstant.SPACE)
                    .append((CommonConstant.TO_UPPER_CASE_Y.equals(formColumnMeta.getIsNullable()) ? DataBaseConstant.SQL_NULL : DataBaseConstant.SQL_NOT_NULL));
        } else if (DataBaseConstant.INT.equalsIgnoreCase(formColumnMeta.getColumnType())) {
            sql.append(formColumnMeta.getColumnName()).append(DataBaseConstant.SPACE).append(DataBaseConstant.INT).append(DataBaseConstant.LEFT_BRACKET)
                    .append(formColumnMeta.getColumnSize()).append(DataBaseConstant.RIGHT_BRACKET).append(DataBaseConstant.SPACE)
                    .append((CommonConstant.TO_UPPER_CASE_Y.equals(formColumnMeta.getIsNullable()) ? DataBaseConstant.SQL_NULL : DataBaseConstant.SQL_NOT_NULL));
        } else if (DataBaseConstant.DOUBLE.equalsIgnoreCase(formColumnMeta.getColumnType())) {
            sql.append(formColumnMeta.getColumnName()).append(DataBaseConstant.SPACE).append(DataBaseConstant.DOUBLE).append(DataBaseConstant.LEFT_BRACKET).append(formColumnMeta.getColumnSize())
                    .append(DataBaseConstant.COMMA).append(formColumnMeta.getDecimalDigits()).append(DataBaseConstant.RIGHT_BRACKET).append(DataBaseConstant.SPACE)
                    .append((CommonConstant.TO_UPPER_CASE_Y.equals(formColumnMeta.getIsNullable()) ? DataBaseConstant.SQL_NULL : DataBaseConstant.SQL_NOT_NULL));
        } else if (DataBaseConstant.BIG_DECIMAL_.equalsIgnoreCase(formColumnMeta.getColumnType())) {
            sql.append(formColumnMeta.getColumnName()).append(DataBaseConstant.SPACE).append(DataBaseConstant.DECIMAL).append(DataBaseConstant.LEFT_BRACKET).append(formColumnMeta.getColumnSize())
                    .append(DataBaseConstant.COMMA).append(formColumnMeta.getDecimalDigits()).append(DataBaseConstant.RIGHT_BRACKET).append(DataBaseConstant.SPACE)
                    .append((CommonConstant.TO_UPPER_CASE_Y.equals(formColumnMeta.getIsNullable()) ? DataBaseConstant.SQL_NULL : DataBaseConstant.SQL_NOT_NULL));
        } else if (DataBaseConstant.TEXT_.equalsIgnoreCase(formColumnMeta.getColumnType())) {
            sql.append(formColumnMeta.getColumnName()).append(DataBaseConstant.SPACE).append(DataBaseConstant.TEXT_).append(DataBaseConstant.SPACE)
                    .append((CommonConstant.TO_UPPER_CASE_Y.equals(formColumnMeta.getIsNullable()) ? DataBaseConstant.SQL_NULL : DataBaseConstant.SQL_NOT_NULL));
        } else if (DataBaseConstant.BLOB_.equalsIgnoreCase(formColumnMeta.getColumnType())) {
            sql.append(formColumnMeta.getColumnName()).append(DataBaseConstant.SPACE).append(DataBaseConstant.BLOB_).append(DataBaseConstant.SPACE)
                    .append((CommonConstant.TO_UPPER_CASE_Y.equals(formColumnMeta.getIsNullable()) ? DataBaseConstant.SQL_NULL : DataBaseConstant.SQL_NOT_NULL));
        } else if (DataBaseConstant.LONG.equalsIgnoreCase(formColumnMeta.getColumnType())) {
            sql.append(formColumnMeta.getColumnName()).append(DataBaseConstant.SPACE).append(DataBaseConstant.BIGINT_).append(DataBaseConstant.SPACE)
                    .append((CommonConstant.TO_UPPER_CASE_Y.equals(formColumnMeta.getIsNullable()) ? DataBaseConstant.SQL_NULL : DataBaseConstant.SQL_NOT_NULL));
        }
        sql.append((ConvertUtils.isNotEmpty(formColumnMeta.getColumnComment()) ? DataBaseConstant.SQL_COMMENT + DataBaseConstant.SINGLE_QUOTE + formColumnMeta.getColumnComment() + DataBaseConstant.SINGLE_QUOTE : DataBaseConstant.SPACE));
        sql.append((ConvertUtils.isNotEmpty(formColumnMeta.getColumnDefaultValue()) ? DataBaseConstant.SQL_DEFAULT + formColumnMeta.getColumnDefaultValue() : DataBaseConstant.SPACE));
        String primaryKeyType = formColumnMeta.getPrimaryKeyType();
        boolean autoIncrement = "SEQUENCE".equalsIgnoreCase(primaryKeyType) || "NATIVE".equalsIgnoreCase(primaryKeyType);
        if (ConverterIgnoreConstant.ID.equalsIgnoreCase(formColumnMeta.getColumnName()) && primaryKeyType != null && autoIncrement) {
            sql.append(" AUTO_INCREMENT ");
        }
        return sql.toString();
    }

    /**
     * 获取添加字段描述
     *
     * @param formColumnMeta - 前端表单
     * @return String - SQL语句
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/10 14:17
     */
    private String getAddFieldDesc(final ColumnMeta formColumnMeta) {
        String result = this.getFieldDesc(formColumnMeta, null);
        return result;
    }

    /**
     * 获取重命名字段描述
     *
     * @param formColumnMeta - 前端表单
     * @return String - SQL语句
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/10 14:17
     */
    private String getRenameFieldDesc(final ColumnMeta formColumnMeta) {
        String result = this.getFieldDesc(formColumnMeta, null);
        return result;
    }

    /**
     * 获取更新字段描述
     *
     * @param formColumnMeta - 前端表单
     * @param dataColumnMeta - 数据库表
     * @return String - SQL语句
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/10 14:17
     */
    private String getUpdateFieldDesc(final ColumnMeta formColumnMeta, final ColumnMeta dataColumnMeta) {
        String result = this.getFieldDesc(formColumnMeta, dataColumnMeta);
        return result;
    }

    @Override
    public String getAddColumnSql(final ColumnMeta columnMeta) {
        return DataBaseConstant.SQL_ADD + DataBaseConstant.SQL_COLUMN + getAddFieldDesc(columnMeta) + DataBaseConstant.SEMICOLON;
    }

    @Override
    public String getReNameFieldName(final ColumnMeta columnMeta) {
        return DataBaseConstant.SQL_CHANGE + DataBaseConstant.SQL_COLUMN + columnMeta.getOldColumnName() + DataBaseConstant.SPACE + getRenameFieldDesc(columnMeta) + DataBaseConstant.SPACE + DataBaseConstant.SEMICOLON;
    }

    @Override
    public String getUpdateColumnSql(final ColumnMeta formColumnMeta, final ColumnMeta dataColumnMeta) {
        return DataBaseConstant.SQL_MODIFY + DataBaseConstant.SQL_COLUMN + getUpdateFieldDesc(formColumnMeta, dataColumnMeta) + DataBaseConstant.SEMICOLON;
    }

    @Override
    public String getMatchClassTypeByDataType(final String dataType, final int digits) {
        String result = DataBaseConstant.EMPTY;
        if (DataBaseConstant.VARCHAR.equalsIgnoreCase(dataType)) {
            result = DataBaseConstant.STRING;
        } else if (DataBaseConstant.DOUBLE.equalsIgnoreCase(dataType)) {
            result = DataBaseConstant.DOUBLE;
        } else if (DataBaseConstant.INT.equalsIgnoreCase(dataType)) {
            result = DataBaseConstant.INT;
        } else if (DataBaseConstant.DATE.equalsIgnoreCase(dataType)) {
            result = DataBaseConstant.DATE_;
        } else if (DataBaseConstant.DATE_TIME.equalsIgnoreCase(dataType)) {
            result = DataBaseConstant.DATE_;
        } else if (DataBaseConstant.DECIMAL.equalsIgnoreCase(dataType)) {
            result = DataBaseConstant.BIG_DECIMAL_;
        } else if (DataBaseConstant.TEXT_.equalsIgnoreCase(dataType)) {
            result = DataBaseConstant.TEXT_;
        } else if (DataBaseConstant.BLOB_.equalsIgnoreCase(dataType)) {
            result = DataBaseConstant.BLOB_;
        }
        return result;
    }

    @Override
    public String dropTableSql(final String tableName) {
        return DataBaseConstant.SQL_DROP + DataBaseConstant.SQL_TABLE + DataBaseConstant.SQL_IF + DataBaseConstant.SQL_EXISTS + tableName + DataBaseConstant.SPACE + DataBaseConstant.SEMICOLON;
    }

    @Override
    public String getDropColumnSql(final String fieldName) {
        return DataBaseConstant.SQL_DROP + DataBaseConstant.SQL_COLUMN + fieldName + DataBaseConstant.SEMICOLON;
    }

    /**
     * Mysql注释是和修改的sql一起的,所以返回空字符串就可以了
     *
     * @param columnMeta -
     * @return String - SQL语句
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/3 10:02
     */
    @Override
    public String getColumnCommentSql(final ColumnMeta columnMeta) {
        return DataBaseConstant.EMPTY;
    }

    @Override
    public String getSpecialHandle(final ColumnMeta formColumnMeta, final ColumnMeta dataColumnMeta) {
        return null;
    }

    @Override
    public String creatIndexes(final TableIndex tableIndex, final String tableName) {
        StringBuilder sql = new StringBuilder();
        if (!CommonConstant.DEL_FLAG_DELETE.equals(tableIndex.getDelFlag()) && CommonConstant.TO_UPPER_CASE_N.equals(tableIndex.getIsSynchronize())) {
            String indexName = tableIndex.getIndexName();
            String indexField = tableIndex.getIndexField();
            String indexType = DataBaseConstant.NORMAL_SYNCHRONIZATION.equals(tableIndex.getIndexType()) ? DataBaseConstant.SQL_INDEX : tableIndex.getIndexType() + DataBaseConstant.SQL_INDEX;
            sql.append(DataBaseConstant.SQL_CREATE).append(indexType).append(indexName).append(DataBaseConstant.SQL_ON).append(tableName).append(DataBaseConstant.LEFT_BRACKET).append(indexField).append(DataBaseConstant.RIGHT_BRACKET);
        }
        return sql.toString();
    }

    @Override
    public String dropIndexes(final String indexName, final String tableName) {
        return DataBaseConstant.SQL_DROP + DataBaseConstant.SQL_INDEX + indexName + DataBaseConstant.SQL_ON + tableName;
    }

    @Override
    public String countIndex(final String indexName, final String tableName) {
        return DataBaseConstant.SQL_SELECT + DataBaseConstant.SQL_COUNT + DataBaseConstant.SQL_FROM + "information_schema.statistics" + DataBaseConstant.SQL_WHERE + "table_name" + DataBaseConstant.SPACE + DataBaseConstant.EQUALS + DataBaseConstant.SPACE + DataBaseConstant.SINGLE_QUOTE + tableName + DataBaseConstant.SINGLE_QUOTE + DataBaseConstant.SQL_AND + "index_name" + DataBaseConstant.SPACE + DataBaseConstant.EQUALS + DataBaseConstant.SPACE + DataBaseConstant.SINGLE_QUOTE + indexName + DataBaseConstant.SINGLE_QUOTE;
    }

}
